#!/usr/local/bin/python
################################################################################
# decoder.py
#
# UTF8SMTP NIDAMail Program
# Version 1.0
# Date : July 23, 2008
# Homepage: http://sourceforge.net/projects/utf8smtp/
################################################################################

# Import 3rd party PyDNS library (http://pydns.sourceforge.net)
import DNS
import threading, time, os, re, spf
from subprocess import *
from distutils import file_util
from email import base64MIME, quopriMIME

import common

# Configuration
vh = common.vh
conf = common.conf
access = common.access

################################################################################
def toEncoder(from_name, from_email, to_email, subject, contents):

	try:
		key19 = common.makeKEY19(0)

		# /NIDAMail_Data/ENCODING/original/key19_original
		f = open('%s/original/%s_original' % (conf['ENCODE_QUEUE'], key19), 'w')
		f.write(contents)
		f.close()

		f = open('%s/before/%s' % (conf['ENCODE_QUEUE'], key19), 'w')
		f.write('FROM_CHARSET=utf-8\r\n')
		f.write('TO_CHARSET=%s\r\n' % conf['CHARSET'])
		f.write('MAIL_FROM=%s\r\n' % from_email)
		f.write('FROM_NAME=%s\r\n' % from_name)
		f.write('FROM_EMAIL=%s\r\n' % from_email)
		f.write('TO=%s\r\n' % to_email)
		f.write('SUBJECT=%s\r\n' % subject)
		f.write('MAINTEXT=%s_original\r\n' % key19)
		f.close()

		# /NIDAMail_Data/ENCODING/before/key19_original -> /NIDAMail_Data/ENCODING/key19
		os.rename('%s/before/%s' % (conf['ENCODE_QUEUE'], key19), '%s/%s' % (conf['ENCODE_QUEUE'], key19))

	except:
		common.printLOG("decoder | Can't toEncoder(%s, %s, %s, subject, contents)" % (from_name, from_email, to_email), 'error')
		return -1
	else: return 1

################################################################################
# toSender(mail['MAIL_FROM'], relaylist, relaylist_alt, key19)
################################################################################
def toSender(mail_from, mail_from_alt, rcptlist, rcptlist_alt, original_key19):

	try:
		key19 = common.makeKEY19(0)

		# /NIDAMail_Data/DECODING/ing/original_key19
		f = open('%s/ing/%s' % (conf['DECODE_QUEUE'], original_key19), 'r')

		# /NIDAMail_Data/SEND/original/key19_original
		f2 = open('%s/original/%s_original' % (conf['SEND_QUEUE'], key19), 'w')

		for lineStr in f:
			f2.write(lineStr)
		f2.close()
		f.close()

		# /NIDAMail_Data/SEND/before/key19
		f = open('%s/before/%s' % (conf['SEND_QUEUE'], key19), 'w')
		f.write('MAIL_FROM=%s\r\n' % mail_from)
		f.write('MAIL_FROM_ALT=%s\r\n' % mail_from_alt)
		print "#######################################################"
		print mail_from
		print "#######################################################"
		print mail_from_alt
		print "#######################################################"


		# Multiple receiptors
		for rcpt_to in rcptlist: 
			f.write('TO=%s\r\n' % rcpt_to)
		###################################################################
		for rcpt_to_alt in rcptlist_alt: 
			f.write('TO_ALT=%s\r\n' % rcpt_to_alt)
		###################################################################

		f.close()

		# /NIDAMail_Data/SEND/before/key19 -> /NIDAMail_Data/SEND/key19
		os.rename('%s/before/%s' % (conf['SEND_QUEUE'], key19), '%s/%s' % (conf['SEND_QUEUE'], key19))

	except:
		common.printLOG("decoder | Can't toSender(%s, rcptlist, %s)" % (mail_from, original_key19), 'error')
		return -1

	else: return 1

################################################################################
def safeQuery(path, sqllist, cnt):
	try:
		connDB = common.connectDB('%s/.sqlite' % path)
		curDB = connDB.cursor()
	except: 
		common.printLOG("decoder | Can't connect to %s" % path, 'error')
		return -1
	else:
		i = 0
		while i < cnt:
			try:
				for sql in sqllist: 
					curDB.execute(sql)
				connDB.commit()
			except: 
				time.sleep(1)
			else: 
				break
			i += 1
		common.closeDB(connDB, curDB)

		if i >= cnt: 
			common.printLOG('decoder | %s' % sql, 'error')
			return -1
		else: 
			return 1

################################################################################
# Save an email information to SQLite DB
################################################################################
def writeMail(key19, key19_first, key19_from, type, errcode, mail, rcptlist, tolist, cclist, bcclist, attachlist):

	############################### REVISE CODE ################################
	szOLDMBOX = mail['MBOX']
	############################### REVISE CODE ################################

	for rcpt_to in rcptlist:   
		mail['MBOX'] = szOLDMBOX

		liTemp = common.searchUserPath(rcpt_to)

		mail['PATH'] = liTemp[0]
		mail['NAME'] = liTemp[2]

		if mail['PATH'] in ('no user', 'no domain'): 
			continue

		sql = []

		#-----------------------------------------------------------------------
		# tolist -> email[]
		#-----------------------------------------------------------------------
		for email in tolist:
			# replace(old, new[, count])
			# type = TO,  email = email[1], name = email[0]
			szTemp = '''INSERT INTO receiverlist (key19, key19_first, type, email, name)
						VALUES ('%s', '%s', 'TO', '%s', '%s');
					 ''' % (key19, key19_first, email[1].replace("'", "''"), email[0].replace("'", "''"))
			sql.append(szTemp)
		#-----------------------------------------------------------------------
		for email in cclist:
			szTemp = '''INSERT INTO receiverlist (key19, key19_first, type, email, name)
						VALUES ('%s', '%s', 'CC', '%s', '%s');
					 ''' % (key19, key19_first, email[1].replace("'", "''"), email[0].replace("'", "''"))
			sql.append(szTemp)
		#-----------------------------------------------------------------------
		for email in bcclist:
			szTemp = '''INSERT INTO receiverlist (key19, key19_first, type, email, name)
						VALUES ('%s', '%s', 'BCC', '%s', '%s');
					 ''' % (key19, key19_first, email[1].replace("'", "''"), email[0].replace("'", "''"))
			sql.append(szTemp)
		#-----------------------------------------------------------------------
		for filename, printname in attachlist:
			szTemp = '''INSERT INTO attachlist (key19, key19_first, filename, printname, size)
						VALUES ('%s', '%s', '%s', '%s', '%d');
					 ''' % (key19, key19_first, filename, printname.replace("'", "''"), os.path.getsize('%s/attach/%s' % (conf['DECODE_QUEUE'], filename)))
			sql.append(szTemp)
			file_util.copy_file('%s/attach/%s' % (conf['DECODE_QUEUE'], filename), '%s/recv/%s' % (mail['PATH'], filename))
		#-----------------------------------------------------------------------
		if type == 'ing':
			szTemp = '''INSERT INTO maillist (key19, mail_from, rcpt_to, message_id, from_name, from_email, to_email, to_cnt, subject, size, attach, contents, mbox, priority, category, readornot, textorhtml, charset)
						VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%d', 1, 1, '%d', '%s');
					 ''' % (key19, mail['MAIL_FROM'].replace("'", "''"), rcpt_to, mail['MESSAGE_ID'], mail['FROM_NAME'].replace("'", "''"), mail['FROM_EMAIL'].replace("'", "''"),
							mail['TO_EMAIL'], mail['TO_CNT'], mail['SUBJECT'].replace("'", "''"), mail['SIZE'], mail['ATTACH_CNT'], mail['MAINTEXT'].replace("'", "''"), mail['MBOX'],
					mail['PRIORITY'], mail['TEXTORHTML'], mail['CHARSET'])
			sql.append(szTemp)
		elif type == 'rfc822':
			szTemp = '''INSERT INTO rfc822list (key19, key19_first, key19_from, message_id, from_name, from_email, subject, size, contents, priority, category, textorhtml, charset)
						VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d', 1, '%d', '%s');
					 ''' % (mail['KEY19'], key19_first, key19_from, mail['MESSAGE_ID'], mail['FROM_NAME'].replace("'", "''"), mail['FROM_EMAIL'].replace("'", "''"),
							mail['SUBJECT'].replace("'", "''"), mail['SIZE'], mail['MAINTEXT'].replace("'", "''"), mail['PRIORITY'], mail['TEXTORHTML'], mail['CHARSET'])
			sql.append(szTemp)
		#-----------------------------------------------------------------------
		if safeQuery(mail['PATH'], sql, 3) == -1:

 			for szFILENAME, szPRINTNAME in attachlist: 
			 	common.deleteFile('%s/recv/%s' % (mail['PATH'], szFILENAME), 'decoder')

			if type == 'ing':
				sql = []
				sql.append("DELETE FROM receiverlist WHERE key19_first='%s'" % key19)
				sql.append("DELETE FROM rfc822list WHERE key19_first='%s'" % key19)
				sql.append("DELETE FROM attachlist WHERE key19_first='%s'" % key19)
				safeQuery(mail['PATH'], sql, 3)

			common.printLOG('%s | FAIL(%s) - MBOX: %s, From: %s("%s" <%s>), To: %s, Subject: %s' % (key19, type, mail['MBOX'], mail['MAIL_FROM'], mail['FROM_NAME'], mail['FROM_EMAIL'], rcpt_to, mail['SUBJECT']), 'decoder')

		else:
			if type == 'ing': 
				file_util.copy_file('%s/ing/%s' % (conf['DECODE_QUEUE'], key19), '%s/recv/%s' % (mail['PATH'], key19))

			nowsize = common.get_nowsize(rcpt_to)

			if nowsize >= 0: 
				common.update_nowsize(rcpt_to, nowsize)

			common.printLOG('%s | WRITE(%s) - MBOX: %s, From: %s("%s" <%s>), To: %s, Subject: %s' % (key19, type, mail['MBOX'], mail['MAIL_FROM'], mail['FROM_NAME'], mail['FROM_EMAIL'], rcpt_to, mail['SUBJECT']), 'decoder')

################################################################################
# decodeMIME(file, file, file, 'ing', '')
################################################################################
def decodeMIME(key19, key19_first, key19_from, type, errcode):
	mail = {'KEY19':key19,
			'FROM_IP':'',
			'MBOX':'',
			'MAIL_FROM':'',
			'MAIL_FROM_ALT':'',
			'MESSAGE_ID':'',
			'DATE':0,
			'FROM_NAME':'',
			'FROM_EMAIL':'',
			'TO_NAME':'',
			'TO_EMAIL':'',
			'TO_CNT':0,
			'SUBJECT':'',
			'SIZE':0,
			'ATTACH_CNT':0,
			'MAINTEXT':'',
			'PRIORITY':3,
			'INSERTAD':0,
			'TEXTORHTML':0,
			'CHARSET':conf['CHARSET'],
			'CONTENT_TYPE':'text/plain',
			'CONTENT_ID':'',
			'IS_ALLOW':0,
			'ERR_TABLE':'',
			'ERR_SENDKEY':'',
			'ERRCODE':errcode,
			'PATH':'',
			'NAME':'',
			'ENCODING':'',
			'HTML':'',
			'TEXT':'',
			'ATTACH':''
			}

	rcptlist = []
	relaylist = []
	relaylist_alt = []
	tolist = []
	cclist = []
	bcclist = []
	attachlist = []
	rfc822list = []
	boundary = ['']

	# /NIDAMail_Data/DECODING/type/key19
	szFILE = '%s/%s/%s' % (conf['DECODE_QUEUE'], type, key19)

	mail['SIZE'] = os.path.getsize(szFILE)

	try: 
		f = open(szFILE, 'r')
	except: 
		lineStr = ''
		common.printLOG("decoder | Can't open %s/%s" % (conf['DECODE_QUEUE'], key19), 'error')
	else: 
		lineStr = f.readline()

	# Message line processing
	while lineStr:
		nextStr = f.readline()

		if nextStr and nextStr[0] in ('\t', ' '):
			lineStr = '%s %s' % (lineStr.rstrip(), nextStr.lstrip())
			continue
		else: 
			lineStr = lineStr.strip()

		cmdStr = lineStr.upper()

		#-----------------------------------------------------------------------
		# IS_ALLOW:
		#-----------------------------------------------------------------------
		if cmdStr.startswith('IS_ALLOW: YES'): 
			mail['IS_ALLOW'] = 1
		#-----------------------------------------------------------------------
		# FROM_IP:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('FROM_IP:'): 
			mail['FROM_IP'] = lineStr[8:].strip()
		#-----------------------------------------------------------------------
		# X-MBOX:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('X-MBOX:'):
			mail['MBOX'] = lineStr[7:].strip()
		#-----------------------------------------------------------------------
		# MAIL FROM:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('MAIL FROM:'):
			print "cmdStr: " + cmdStr
			mail['MAIL_FROM'] = lineStr[10:].strip().strip('<>').lower()
		#-----------------------------------------------------------------------
		# MAIL FROM ALT:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('MAIL FROM ALT:'):
			print "cmdStr: " + cmdStr
			mail['MAIL_FROM_ALT'] = lineStr[14:].strip().strip('<>').lower()
		#-----------------------------------------------------------------------
		# RCPT TO:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('RCPT TO:'):
			email = lineStr[8:].strip().strip('<>').lower()
			rcptlist.append(email)
		#-----------------------------------------------------------------------
		# RELAY TO:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('RELAY TO:'): 
			relaylist.append(lineStr[9:].strip().strip('<>').lower())
		#-----------------------------------------------------------------------
		# RELAY TO ALT:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('RELAY TO ALT:'): 
			relaylist_alt.append(lineStr[13:].strip().strip('<>').lower())
		#-----------------------------------------------------------------------
		# DATE:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('DATE:'): 
			try: 
				mail['DATE'] = time.mktime(time.strptime(lineStr[5:].replace('GMT', '+').replace('KST', '+').replace('-', '+').split('+')[0].strip(), '%a, %d %b %Y %X'))
			except: 
				common.printLOG("decoder | Can't strptime(%s)" % lineStr[5:].strip(), 'error')
				mail['DATE'] = time.time()
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('MESSAGE-ID:'): 
			mail['MESSAGE_ID'] = lineStr[11:].strip().strip('<>')
		#-----------------------------------------------------------------------
		# FROM:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('FROM:'):
			# Three cases
			# 'FROM: "김재연" <김재연@김재연.kr <jaeyounkim@cslab.net>>'
			# 'FROM: "김재연" <김재연@김재연.kr>'
			# 'FROM: <김재연@김재연.kr>'
			szTemp = lineStr[5:].strip().split('<')
			print "szTemp: " + str(szTemp);
			print "Len: " + str(len(szTemp))
			 
			if len(szTemp) > 2: 
				szTemp[2] = szTemp[2].strip('>')
				print "2 :" + szTemp[2]

			# If there is no <>
			if len(szTemp) == 1: 
				mail['FROM_NAME'] = ''
				mail['FROM_EMAIL'] = common.decodeCHARSET(szTemp[0].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first).strip()
			# If there is no ALT-ADDRESS
			elif len(szTemp) == 2:
				mail['FROM_NAME'] = common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first).strip()
				mail['FROM_EMAIL'] = common.decodeCHARSET(szTemp[1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first).strip()
			# If there is ALT-ADDRESS
			elif len(szTemp) > 2: 
				mail['FROM_NAME'] = common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first).strip()
				mail['FROM_EMAIL'] = common.decodeCHARSET(szTemp[1].strip().strip('<>') + "," + szTemp[2], mail['CHARSET'], 'utf-8', 'decoder', key19_first).strip()
			else:
				mail['FROM_NAME'] = ''
				mail['FROM_EMAIL'] = ''
				print "Exception Error"

			print "FROM_EMAIL: " + str(mail['FROM_EMAIL'])
			print "========================================================="
		#-----------------------------------------------------------------------
		# TO:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('TO:'):
			#lineStr = 'TO: "김재연" <김재연@테스트.kr <jaeyounkim@mail.cslab.kr>>'
			# Multiple TO
			liTemp = lineStr[3:].strip().replace(';', ',').split(',')

			emailExt = ''

			for email in liTemp:
				emailExt += email

				# If there is no @, continue (email = NAME)
				if email.find('@') == -1: 
					continue

				szTemp = emailExt.strip().split('<')

				print "Len: " + str(len(szTemp))

				if len(szTemp) > 2:
					szTemp[2] = szTemp[2].strip('>')

				#print "0 :" + szTemp[0]
				#print "1 :" + szTemp[1]

				if len(szTemp) > 2:
					print "2 :" + szTemp[2]

				emailExt = ''

				#---------------------------------------------------------------
				# Add a value to tolist array
				#---------------------------------------------------------------
				if len(szTemp) == 2:
					as1 = common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)
					as2 = common.decodeCHARSET(szTemp[1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)
					as = [str(as1), str(as2)]
  					tolist.append(as)
				elif len(szTemp) > 2:
					as1 = common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)
					as2 = common.decodeCHARSET(szTemp[1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first) + "," + szTemp[2]
					as = [str(as1), str(as2)]
  					tolist.append(as)
				else: 
					as = ['', szTemp[-1].strip().strip('<>')]
					print "4: " + str(as)				
					tolist.append(as)

				mail['TO_CNT'] += 1
				print "========================================================="

			# Multiple RCPT TO
			if len(tolist) > 1:
				mail['TO_NAME'] = tolist[0][0]
				#print mail['TO_NAME']
				mail['TO_EMAIL'] = tolist[0][1].replace("'", "")
				#print mail['TO_EMAIL']
		#-----------------------------------------------------------------------
		# CC:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('CC:'):

			liTemp = lineStr[3:].strip().replace(';', ',').split(',')
			emailExt = ''

			for email in liTemp:
				emailExt += email

				if email.find('@') == -1: 
					continue

				szTemp = emailExt.strip().split('<')
				emailExt = ''

			if len(szTemp) > 1:
  				cclist.append([common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first), 
								   common.decodeCHARSET(szTemp[-1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)])
			else: 
				cclist.append(['', common.decodeCHARSET(szTemp[-1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)])

			mail['TO_CNT'] += 1
		#-----------------------------------------------------------------------
		# BCC:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('BCC:'):
			liTemp = lineStr[4:].strip().replace(';', ',').split(',')
			emailExt = ''
			for email in liTemp:
				emailExt += email
				if email.find('@') == -1: continue
				szTemp = emailExt.strip().split('<')
				emailExt = ''
			if len(szTemp) > 1:
  				bcclist.append([common.decodeCHARSET(szTemp[0].strip().strip('\'"<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first), 
								   common.decodeCHARSET(szTemp[-1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)])
			else: 
				bcclist.append(['', common.decodeCHARSET(szTemp[-1].strip().strip('<>'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)])
			mail['TO_CNT'] += 1
		#-----------------------------------------------------------------------
		# SUBJECT:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('SUBJECT:'): 
			mail['SUBJECT'] += common.decodeCHARSET(lineStr[8:].rstrip(), mail['CHARSET'], 'utf-8', 'decoder', key19_first)
		#-----------------------------------------------------------------------
		# BOUNDARY:
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('BOUNDARY='): 
			boundary.append('--'+lineStr[9:].strip().strip('"'))
		#-----------------------------------------------------------------------
		# CONTENT-TYPE
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('CONTENT-TYPE:'):
			szTemp = lineStr[13:].strip().split(';')
			for szTemp2 in szTemp:
				szTemp3 = szTemp2.split('=')
				if szTemp3[0].strip().lower() == 'charset': 
					mail['CHARSET'] = szTemp2[szTemp2.find('=')+1:].strip().strip('"')
				elif szTemp3[0].strip().lower() == 'boundary': 
					boundary.append('--'+szTemp2[szTemp2.find('=')+1:].strip().strip('"'))
				elif szTemp3[0].strip().lower() == 'name': 
					mail['ATTACH'] = common.decodeCHARSET(szTemp2[szTemp2.find('=')+1:].strip().strip('"'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)

			mail['CONTENT_TYPE'] = szTemp[0].strip().lower()
		#-----------------------------------------------------------------------
		# CONTENT-DISPOSITION
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('CONTENT-DISPOSITION:'):
			szTemp = lineStr[20:].strip().split(';')
			for szTemp2 in szTemp:
				szTemp3 = szTemp2.split('=')
				if szTemp3[0].strip().lower() == 'filename': 
					mail['ATTACH'] = common.decodeCHARSET(szTemp2[szTemp2.find('=')+1:].strip().strip('"'), mail['CHARSET'], 'utf-8', 'decoder', key19_first)
		#-----------------------------------------------------------------------
		# CONTENT-TRANSFER-ENCODING
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('CONTENT-TRANSFER-ENCODING:'): 
			mail['ENCODING'] = lineStr[26:].strip().lower()			
		#-----------------------------------------------------------------------
		# CONTENT-ID
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('CONTENT-ID:'): 
			mail['CONTENT_ID'] = lineStr[11:].strip().strip('<').strip('>').replace('/', '')
		#-----------------------------------------------------------------------
		# X-PRIORITY
		#-----------------------------------------------------------------------
		elif cmdStr.startswith('X-PRIORITY:'): 
			try: 
				mail['PRIORITY'] = int(lineStr[11:].strip().split()[0])
			except: 
				pass
		elif cmdStr.startswith('X-ERRCODE:') and mail['ERRCODE'] == '': 
			mail['ERRCODE'] = lineStr[10:].strip()
		#-----------------------------------------------------------------------
		if lineStr == '':
			szTemp = nextStr
			#-------------------------------------------------------------------
			# CONTENT-TYPE = multipart
			#-------------------------------------------------------------------
			if mail['CONTENT_TYPE'].startswith('multipart'):
				while szTemp:
					szTemp = szTemp.strip()
					if szTemp == boundary[-1] and boundary[-1] != '': 
						break
					elif szTemp == boundary[-1]+'--' and boundary[-1] != '':
						boundary.pop()
						break
					szTemp = f.readline()
			#-------------------------------------------------------------------
			# CONTENT-TYPE = text/html
			#-------------------------------------------------------------------
			elif mail['CONTENT_TYPE'] == 'text/html':
				body_contents = ''
				while szTemp:
					if szTemp.strip() == boundary[-1] and boundary[-1] != '': 
						break
					elif szTemp.strip() == boundary[-1]+'--' and boundary[-1] != '':
						boundary.pop()
						break
					if mail['ENCODING'] == 'base64': 
						szTemp = szTemp.strip()
					body_contents += szTemp
					szTemp = f.readline()
				try:
					if mail['ENCODING'] == 'base64': 
						body_contents = base64MIME.decode(body_contents)
					elif mail['ENCODING'] == 'quoted-printable': 
						body_contents = quopriMIME.decode(body_contents)
					mail['HTML'] += common.decodeCHARSET(body_contents, mail['CHARSET'], 'utf-8', 'decoder', key19_first)

				except: 
					common.printError("decoder | Can't decode HTML_BODY(%s, %s)" % (key19, mail['ENCODING']), 'decoder')
			#-------------------------------------------------------------------
			# CONTENT-TYPE = text/plain
			#-------------------------------------------------------------------
			elif mail['CONTENT_TYPE'] == 'text/plain':
				body_contents = ''

				while szTemp:
					if szTemp.strip() == boundary[-1] and boundary[-1] != '': 
						break
					elif szTemp.strip() == boundary[-1]+'--' and boundary[-1] != '':
						boundary.pop()
						break
					if mail['ENCODING'] == 'base64': 
						szTemp = szTemp.strip()
					body_contents += szTemp
					szTemp = f.readline()

				try:
					if mail['ENCODING'] == 'base64': 
						body_contents = base64MIME.decode(body_contents)
					elif mail['ENCODING'] == 'quoted-printable': 
						body_contents = quopriMIME.decode(body_contents)
					mail['TEXT'] += common.decodeCHARSET(body_contents, mail['CHARSET'], 'utf-8', 'decoder', key19_first)
				except: 
					common.printError("decoder | Can't decode TEXT_BODY(%s, %s)" % (key19, mail['ENCODING']), 'decoder')
			#-------------------------------------------------------------------
			# CONTENT-TYPE = message/rfc822' 'message/global
			#-------------------------------------------------------------------
			elif mail['CONTENT_TYPE'] in ('message/rfc822', 'message/global'):

				rfc822_key19 = common.makeKEY19(mail['DATE'])

				# /NIDAMail_Data/DECODING/rfc822/rfc822_key19
				f2 = open('%s/rfc822/%s' % (conf['DECODE_QUEUE'], rfc822_key19), 'w')

				for rcpt_to in rcptlist: 
					f2.write('RCPT TO: <%s>\r\n' % rcpt_to)

				while szTemp:
					szTemp = szTemp.rstrip()
					if szTemp == boundary[-1] and boundary[-1] != '': 
						break
					elif szTemp == boundary[-1]+'--' and boundary[-1] != '':
						boundary.pop()
						break
					f2.write(szTemp+'\r\n')
					szTemp = f.readline()
				f2.close()
				rfc822list.append(rfc822_key19)
			else:
				if mail['CONTENT_ID'] == '': 
					attach_name = '%s_%d' % (key19, len(attachlist))
				else: 
					attach_name = '%s_%s' % (key19, mail['CONTENT_ID'])

				if mail['ATTACH'] == '': 
					mail['ATTACH'] = attach_name

				# /NIDAMail_Data/DECODING/attach/attach_name
				attach_path = '%s/attach/%s' % (conf['DECODE_QUEUE'], attach_name)
				f2 = open(attach_path, 'w')
				attachlist.append([attach_name, mail['ATTACH']])

				body_contents = ''
				#---------------------------------------------------------------
				while szTemp:
					if szTemp.strip() == boundary[-1] and boundary[-1] != '': 
						break
					elif szTemp.strip() == boundary[-1]+'--' and boundary[-1] != '':
						boundary.pop()
						break

					if mail['ENCODING'] == 'base64': 
						szTemp = szTemp.strip()

					body_contents += szTemp
					szTemp = f.readline()

				try:
					if mail['ENCODING'] == 'base64': 
						body_contents = base64MIME.decode(body_contents)
					elif mail['ENCODING'] == 'quoted-printable': 
						body_contents = quopriMIME.decode(body_contents)
				except: 
					common.printLOG("decoder | Can't decode ATTACH(%s, %s)" % (mail['ENCODING'], mail['ATTACH']), 'error')

				f2.write(body_contents)
				f2.close()

			mail['CONTENT_TYPE'] = 'text/plain'
			mail['CONTENT_ID'] = ''
			mail['ATTACH'] = ''
			nextStr = f.readline()

		if nextStr: 
			lineStr = nextStr
		else: 
			break

	try: 
		f.close()
	except: 
		pass

	for rfc822_key19 in rfc822list: 
		decodeMIME(rfc822_key19, key19_first, key19, 'rfc822', mail['ERRCODE'])

	mail['ATTACH_CNT'] = len(attachlist)

	if mail['HTML'] == '':
		mail['TEXTORHTML'] = 0
		mail['MAINTEXT'] = mail['TEXT']
	else:
		mail['TEXTORHTML'] = 1 
		mail['MAINTEXT'] = mail['HTML']

	if type == 'ing': 
		common.removeAttachedHeader('%s/ing/%s' % (conf['DECODE_QUEUE'], key19), 'decoder')

	############################################################################
	# Call toSender function
	############################################################################
	if len(relaylist) > 0 and type == 'ing':
		toSender(mail['MAIL_FROM'], mail['MAIL_FROM_ALT'], relaylist, relaylist_alt, key19)

	############################################################################
	# Call writeMail function
	############################################################################
	if len(rcptlist) > 0: 
		writeMail(key19, key19_first, key19_from, type, errcode, mail, rcptlist, tolist, cclist, bcclist, attachlist)

	for szFILENAME, szPRINTNAME in attachlist: 
		common.deleteFile('%s/attach/%s' % (conf['DECODE_QUEUE'], szFILENAME), 'decoder')

	common.deleteFile('%s/%s/%s' % (conf['DECODE_QUEUE'], type, key19), 'decoder')

################################################################################
# MAIN
################################################################################

# pydns library
DNS.DiscoverNameServers()

common.setUIDGID('decoder')
common.printLOG('decoder | DECODER is started', 'common')  

list = os.listdir('%s/before' % conf['DECODE_QUEUE'])

for file in list:
	try: os.unlink('%s/before/%s' % (conf['DECODE_QUEUE'], file))
	except: common.printLOG("decoder | Can't unlink %s/before/%s" % (conf['DECODE_QUEUE'], file), 'error')

list = os.listdir('%s/attach' % conf['DECODE_QUEUE'])

for file in list:
	try: os.unlink('%s/attach/%s' % (conf['DECODE_QUEUE'], file))
	except: common.printLOG("decoder | Can't unlink %s/attach/%s" % (conf['DECODE_QUEUE'], file), 'error')

list = os.listdir('%s/rfc822' % conf['DECODE_QUEUE'])

for file in list:
	try: os.unlink('%s/rfc822/%s' % (conf['DECODE_QUEUE'], file))
	except: common.printLOG("decoder | Can't unlink %s/rfc822/%s" % (conf['DECODE_QUEUE'], file), 'error')

list = os.listdir('%s/ing' % (conf['DECODE_QUEUE']))

for file in list:
	try: 
		os.rename('%s/ing/%s' % (conf['DECODE_QUEUE'], file), '%s/backup/%s' % (conf['DECODE_QUEUE'], file))
	except: 
		common.printLOG("decoder | Can't rename %s/ing/%s to %s/%s" % (conf['DECODE_QUEUE'], file, conf['DECODE_QUEUE'], file), 'error')

while 1:
	common.loadConf('decoder')
	common.loadVH('decoder')
	common.loadAccess('decoder')

	list = os.listdir(conf['DECODE_QUEUE'])

	for file in list:
		if not file in ('ing', 'before', 'attach', 'rfc822', 'backup'):
			try: 
				# /NIDAMail_Data/DECODING/ -> /NIDAMail_Data/DECODING/ing
				os.rename('%s/%s' % (conf['DECODE_QUEUE'], file), '%s/ing/%s' % (conf['DECODE_QUEUE'], file))
			except: 
				common.printLOG("decoder | Can't rename %s/%s to %s/ing/%s" % (conf['DECODE_QUEUE'], file, conf['DECODE_QUEUE'], file), 'error')

			else: 
				common.printLOG(file, 'decoder')

				if conf['DECODER_TYPE'] == 'fork':
					pid = os.fork()
					if pid == 0:
						# Email Decode
						decodeMIME(file, file, file, 'ing', '')
						os.sys.exit(0)
					th = threading.Thread(target=common.waitPID, args=())
					th.start()
					while(threading.activeCount() > conf['DECODER_MAX_THREADS']):
						common.printLOG('decoder  | fork count is larger than %s' % conf['DECODER_MAX_THREADS'], 'error')
						time.sleep(1)
				elif conf['DECODER_TYPE'] == 'threading':
					th = threading.Thread(target=decodeMIME, args=(file, file, file, 'ing', ''))
					th.start()
					while(threading.activeCount() > conf['DECODER_MAX_THREADS']):
						common.printLOG('decoder | thread count is larger than %s' % (conf['DECODER_MAX_THREADS']), 'error')
						time.sleep(1)
				else: 
					decodeMIME(file, file, file, 'ing', '')
	time.sleep(1)
################################################################################
# End of file	
################################################################################
